/**
 * 表单组件
 */
import React, { Component } from 'react';
import { Form } from 'antd';
import { isEmpty, doActionHandler,isNotNull } from '../common';
import { getUIForm } from '../uiConfig';

import 'moment/locale/zh-cn';

import moment from 'moment';

import UIFormField from './UIFormField';

import UIToolbar from './UIToolbar';

const FormItem = Form.Item;

moment.locale('zh-cn');

class UIFormComponent extends Component {

    constructor(props) {
        super(props);

        if (isEmpty(props.formConfigId)) {
            console.error('UIForm Must With [formConfigId] Property');
        }


        let formConfig = getUIForm(props.formConfigId);

        this.formFieldRefs = [];

        this.state = {
            data: {},
            disabled: props.disabledFileds !== null ? props.disabledFileds : {},
            disabledValues: props.disabledValues !== null ? props.disabledValues : {},
            formParams : props.params,
            formConfig:formConfig
        };
    }

    setFormConfig(formConfig) {
        this.setState({
            formConfig:formConfig
        })
    }

    setFormParams = (params) => {
        this.setState({formParams : params});
        setTimeout(() => {
            this.formFieldRefs.forEach( (filed) => {
                filed.updateFormFiled();
            } );
        });
    }

    addFormFieldOptionItems = (fieldId,optionItems) => {

        this.formFieldRefs.forEach( (filed) => {
            if(fieldId === filed.props.id){
                filed.addOptionItems(optionItems);
            }
        } );
    }

    removeFormFieldOptionItems = (fieldId,optionValues) => {

        this.formFieldRefs.forEach( (filed) => {
            if(fieldId === filed.props.id){
                filed.removeOptionItems(optionValues);
            }
        } );
    }

    setFormFieldParams = (fieldId,params) => {
        //try update field and deliver props to child component - [zy]
        this.setState({
            formParams : this.props.params
        })
        this.formFieldRefs.forEach( (filed) => {
            if(fieldId === filed.props.id){
                filed.setParams(params);
            }
        } );
    }

    getParent = () => {
        return this.props.parent;
    }

    componentDidMount() {
        if (this.props.location && this.props.location.state) {
            this.setFormData(this.props.location.state);
        }
    }

    setDisabledValues = (fieldId, values) => {
        const map = {};
        map[fieldId] = values;
        const disabledValuesMap = { ...this.setState.disabledValues, ...map }
        this.setState({ disabledValues: disabledValuesMap });
    }

    handleAction = (action) => {
        const { actionHandler, history, parent } = this.props;
        const { data } = this.state;
        const actionEvent = {
            actionId: action.actionId,
            action: action.handler,
            component: parent != null ? parent : this,
            params: data
        };
        if (actionHandler !== undefined) {
            if (action.handler.startsWith('/') && history) {
                history.push(action.handler);
            }
            else {
                doActionHandler(actionEvent, actionHandler(actionEvent));
            }
        }
    }

    getFormData = (cb) => {
        const data = this.state.data;
        const { formConfig } = this.state;
        const fieldPropsMap = this.props.fieldPropsMap;
        this.props.form.validateFields((err, values) => {

            formConfig.formProperties.forEach((formField) => {
                if (formField.type === "date") {
                    let dateFormat = 'YYYY-MM-DD';
                    if(isNotNull(fieldPropsMap) && formField.id in fieldPropsMap && 'format' in fieldPropsMap[formField.id]){
                        dateFormat = fieldPropsMap[formField.id]['format']
                    }
                    values[formField.id] = values[formField.id] !== null ? values[formField.id].format(dateFormat) : null;
                }
                if (formField.type === "dateRange") {
                    let dateFormat = 'YYYY-MM-DD';
                    if(isNotNull(fieldPropsMap) && formField.id in fieldPropsMap && 'format' in fieldPropsMap[formField.id]){
                        dateFormat = fieldPropsMap[formField.id]['format']
                    }
                    values[formField.id.split('_')[0]] = values[formField.id][0] !== null ? values[formField.id][0].format(dateFormat) : null;
                    values[formField.id.split('_')[1]] = values[formField.id][1] !== null ? values[formField.id][1].format(dateFormat) : null;
                    delete values[formField.id];
                    delete data[formField.id];
                }
                if(formField.type === "timePicker"){
                    let timeFormat = 'HH:mm:ss';
                    if(isNotNull(fieldPropsMap) && formField.id in fieldPropsMap && 'format' in fieldPropsMap[formField.id]){
                        timeFormat = fieldPropsMap[formField.id]['format']
                    }
                    values[formField.id] = values[formField.id] !== null ? values[formField.id].format(timeFormat) : null;
                }

            });

            if (!err && cb) {
                cb({ ...data, ...values });
            }
        });
    }

    setFormData = (formData,callback) => {
        const { form ,fieldPropsMap} = this.props;

        const { formConfig } = this.state;

        const filedsData = {};

        formConfig.formProperties.forEach((formField) => {

            if (isNotNull(formData) && formField.type === "date") {
                let dateFormat = 'YYYY-MM-DD';
                if(isNotNull(fieldPropsMap) && formField.id in fieldPropsMap && 'format' in fieldPropsMap[formField.id]){
                    dateFormat = fieldPropsMap[formField.id]['format']
                }
                filedsData[formField.id] = isNotNull(formData[formField.id]) ? moment(formData[formField.id], dateFormat) : null;
            }
            else if (isNotNull(formData) && formField.type === "dateRange") {
                let dateFormat = 'YYYY-MM-DD';
                if(isNotNull(fieldPropsMap) && formField.id in fieldPropsMap && 'format' in fieldPropsMap[formField.id]){
                    dateFormat = fieldPropsMap[formField.id]['format']
                }
                filedsData[formField.id] = [isNotNull(formData[formField.id.split('_')[0]]) !== null ? moment(formData[formField.id.split('_')[0]], dateFormat) : null, isNotNull(formData[formField.id.split('_')[1]]) ? moment(formData[formField.id.split('_')[1]], dateFormat) : null];
            }
            else if(isNotNull(formData) && formField.type === "timePicker"){
                let timeFormat = 'HH:mm:ss';
                if(isNotNull(fieldPropsMap) && formField.id in fieldPropsMap && 'format' in fieldPropsMap[formField.id]){
                    timeFormat = fieldPropsMap[formField.id]['format']
                }
                filedsData[formField.id] = isNotNull(formData[formField.id]) ? moment(formData[formField.id], timeFormat) : null;
            }
            else if (isNotNull(formData) &&formField.type === "checkBox") {
                //filedsData[formField.id] = (true === formData[formField.id] || 'true' === formData[formField.id]);
                filedsData[formField.id] = formData[formField.id];
            }
            else if(isNotNull(formData) &&formField.type === "list") {
                if(isNotNull(formData[formField.id])) {
                    filedsData[formField.id] = formData[formField.id];
                }
            }
            else if(isNotNull(formData) &&formField.type === "autoComplete"){
                filedsData[formField.id] = isNotNull( formData[formField.id]) ? formData[formField.id] : null;
            }
            else if(isNotNull(formData)){
                filedsData[formField.id] = isNotNull( formData[formField.id]) ? formData[formField.id] : null;
            }

            if(callback){
                callback(formField,formData,filedsData);
            }
        });
        form.setFieldsValue(filedsData);
        this.setState({ data: { ...formData, ...filedsData } });
    }

    setFieldsValue = (fieldValue) => {
        const { form } = this.props;
        const formData = this.state.data;
        form.setFieldsValue(fieldValue);
        this.setState({ data: { ...formData, ...fieldValue } });
    }

    resetForm = () => {
        const { form } = this.props;
        form.resetFields();
    }

    render() {

        const { getFieldDecorator } = this.props.form;

        const fieldPropsMap = this.props.fieldPropsMap;

        const formItemLayout = {
            labelCol: {
                xs: { span: 24 },
                sm: { span: 6 },
            },
            wrapperCol: {
                xs: { span: 24 },
                sm: { span: 18 },
            },
        };

        this.fomeFields = this.state.formConfig.formProperties.map((formField,index) => {

            let extendProps = {};

            if(isNotNull(fieldPropsMap) && formField.id in fieldPropsMap){
                extendProps = fieldPropsMap[formField.id];
            }

            return <UIFormField 
                        id={formField.id} 
                        fieldRender={this.props.fieldRender} 
                        ref={(inst) => this.formFieldRefs[index] = inst} 
                        disabledValues={this.props.disabledValues !== undefined ? this.props.disabledValues[formField.id] : []} 
                        disabled={this.props.disabledFileds !== undefined ? this.props.disabledFileds[formField.id] : false} 
                        key={formField.id} formField={formField} 
                        formItemLayout={formItemLayout} 
                        fieldDecorator={getFieldDecorator} 
                        params={this.state.formParams} 
                        extendProps = {extendProps}
                    />
        });

        return (
            <Form >
                {this.fomeFields}
                {
                    isEmpty(this.props.actionGroupId) === false ?
                        (
                            <FormItem
                                wrapperCol={{
                                    xs: { span: 24, offset: 0 },
                                    sm: { span: 18, offset: 5 },
                                }}
                            >
                                <UIToolbar actionGroupId={this.props.actionGroupId} ref="toolbar" history={this.props.history} location={this.props.location} parent={this} actionHandler={this.props.actionHandler} />
                            </FormItem>
                        ) : null
                }
            </Form>
        );
    }
}

const UIForm = Form.create({
    onValuesChange : (props, changedValues, allValues) => {
        if(props.onValuesChange !== undefined){
            props.onValuesChange(changedValues, allValues);
        }
    }
})(UIFormComponent);

export default UIForm;
